package com.cms.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cms.entity.Admin;
import com.cms.service.AdminService;

@SuppressWarnings("deprecation")
@Service("userService")
public class AdminServiceImpl extends BaseServiceImpl implements AdminService {

	private static final Logger LOG = LoggerFactory
			.getLogger(AdminService.class);

	@Transactional
	public void recordLogin(String username, String remoteAddr) {
		Admin user = baseDao.getByProperty(Admin.class, "username", username);
		if (user != null) {
			user.setPreLoginTime(user.getLastLoginTime());
			user.setPreLoginAddr(user.getLastLoginAddr());
			user.setLastLoginTime(new Date());
			user.setLastLoginAddr(remoteAddr);
			user.setLoginFailureCount(0);
			baseDao.save(user);
		}
	}

	@Transactional(readOnly = true)
	public List<Admin> listUsers() {
		return baseDao.find(Admin.class);
	}

	@Transactional(readOnly = true)
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		try {
			Admin user = baseDao.get(Admin.class,username);
			if (user == null) {
				throw new UsernameNotFoundException(username);
			}
			return user;
		} catch (Exception e) {
			throw new UsernameNotFoundException(username);
		}
	}

	@Transactional
	public boolean createUser(Admin user) {
		try {
			PasswordEncoder encoder = new MessageDigestPasswordEncoder("md5");
			user.setPassword(encoder.encodePassword(user.getPassword(), null));
			baseDao.save(user);
			return true;
		} catch (Exception e) {
			LOG.error(e.toString());
		}
		return false;
	}

	@Transactional
	public boolean updateUser(Admin user) {
		try {
			baseDao.update(user);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	@Transactional(readOnly = true)
	public List<Admin> listDateUsers(String userName, String realName,
			Integer from, Integer to) {

		// 查询结果
		List<Object> any = new ArrayList<Object>();
		any.add(Transformers.aliasToBean(Admin.class));
		any.add(Restrictions.ne("username", "admin"));
		if (StringUtils.isNotBlank(userName)) {
			any.add(Restrictions.eq("username", userName.trim()));
		}
		if (StringUtils.isNotBlank(realName)) {
			any.add(Restrictions.like("realname", realName.trim(),
					MatchMode.ANYWHERE));
		}
		any.add(Projections.property("username").as("username"));
		any.add(Projections.property("realname").as("realname"));
		any.add(Projections.property("department").as("department"));
		any.add(Projections.property("enabled").as("enabled"));

		any.add(Projections.property("lastLoginTime").as("lastLoginTime"));
		any.add(Projections.property("lastLoginAddr").as("lastLoginAddr"));
		any.add(Projections.property("preLoginTime").as("preLoginTime"));
		any.add(Projections.property("preLoginAddr").as("preLoginAddr"));
		any.add(Projections.property("loginFailureCount").as(
				"loginFailureCount"));
		any.add(Projections.property("lastModifyPsdDate").as(
				"lastModifyPsdDate"));
		any.add(Projections.property("status").as("status"));
		return baseDao.findByAny(Admin.class, from,
				to, any.toArray());
	}

	@Transactional
	public Long getCount(String userName, String realName) {
		// 查询结果
		List<Criterion> any = new ArrayList<Criterion>();
		// 查询条件
		if (StringUtils.isNotBlank(userName)) {
			any.add(Restrictions.eq("username", userName.trim()));
		}
		if (StringUtils.isNotBlank(realName)) {
			any.add(Restrictions.like("realname", realName.trim(),
					MatchMode.ANYWHERE));
		}
		return baseDao.countByAny(Admin.class,
				any.toArray(new Criterion[any.size()]));
	}

	@Transactional
	public void removeById(String username) {
		try {
			Admin user = baseDao.load(Admin.class, username);
			baseDao.delete(user);
		} catch (Exception e) {
			LOG.error(e.toString());
		}
	}

	@Transactional
	public Admin loadUser(String userName) {
		return baseDao.get(Admin.class,userName);
	}

}
